package com.wjc.train.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.wjc.train.business.entity.ConfirmOrder;
import com.wjc.train.business.enums.ConfirmOrderStatusEnum;
import com.wjc.train.business.enums.RocketMqTopicEnum;
import com.wjc.train.business.repository.ConfirmOrderRepository;
import com.wjc.train.business.req.ConfirmOrderSaveReq;
import com.wjc.train.business.service.IBeforeConfirmOrderService;
import com.wjc.train.business.service.ISkTokenService;
import com.wjc.train.common.context.LoginMemberContext;
import com.wjc.train.common.exception.BusinessException;
import com.wjc.train.common.exception.BusinessExceptionCode;
import com.wjc.train.common.untils.CopyUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.redisson.api.RedissonClient;
import org.slf4j.MDC;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 确认订单前的校验
 * </p>
 *
 * @author Guessed
 * @since 2023-08-15
 */
@Service
@Slf4j
public class BeforeConfirmOrderServiceImpl implements IBeforeConfirmOrderService {

    @Resource
    private RedissonClient redissonClient;

    @Resource
    private ISkTokenService skTokenService;

    @Resource
    private ConfirmOrderRepository confirmorderRepository;

    /*
      *springboot3中注入mq失败，因为在该版本spring.factories被移除
      * 替代方案为META-INFO/spring/org
     */
    @Resource
    private RocketMQTemplate rocketMQTemplate;

    @Override
    public Long beforeDoConfirm(ConfirmOrderSaveReq confirmorderSaveReq){
        //省略业务数据校验,车次是否存在，余票是否足够，车次是否在有效期内，传入车票需大于0,同乘客同车次是否已经买过
        Date date = confirmorderSaveReq.getDate();
        String trainCode = confirmorderSaveReq.getTrainCode();
        confirmorderSaveReq.setMemberId(LoginMemberContext.getId());

        //校验令牌
        boolean vaildateSkToken = skTokenService.vaildateSkToken(date, trainCode, LoginMemberContext.getId());
        if(!vaildateSkToken){
            log.info("令牌校验失败");
            throw new BusinessException(BusinessExceptionCode.CONFIRM_ORDER_SK_EXP);
        }
        log.info("令牌校验通过");

        //先保存订单记录
        //订单先入库,状态初始
        ConfirmOrder orderCopy = CopyUtil.copy(confirmorderSaveReq, ConfirmOrder.class);
        orderCopy.setStatus(ConfirmOrderStatusEnum.INIT.getCode());
        orderCopy.setTickets(JSON.toJSONString(confirmorderSaveReq.getTickets()));
        confirmorderRepository.save(orderCopy);

        //可以购票，发送MQ
        log.info("准备发送MQ,等待出票");
        confirmorderSaveReq.setOrderId(orderCopy.getId());
        confirmorderSaveReq.setLogId(MDC.get("LOG_ID"));
        String reqJson = JSON.toJSONString(confirmorderSaveReq);
        log.info("排队购票,发送mq开始，消息:{}",reqJson);
        //设置消息业务唯一ID
        Map<String, Object> headers = new HashMap<>();
        headers.put("key", IdWorker.getId());
        rocketMQTemplate.convertAndSend(RocketMqTopicEnum.CONFIRM_ORDER.getCode(),reqJson,headers);
        log.info("排队购票,发送mq结束");
        return orderCopy.getId();
    }


}
